boolean rxActive, connected, valbool = 0;
int bitcnt, bytcnt,gpcnt ,VBtimeout,timeout = 0;

//Copyright ID Innovations//
//All users may freely use or copy or adapt for pleasure or profit. A mention to ID Innovations or George Powell
//would be well received. Have fun!

//Brief description 
//This code 'DEMO' only code is meant to be used with ID Innovations ID12LA card reader module and,
//for the adventurous, a companion free VB demo application available at www.ID-innovations.com that reads 
//and stores tags with time-date and door-strike activation, but it can be used in a 'stand alone' mode
//using the arduino 'monitor' tool.
//Warning. Never use the demo VB program where loss of life, injury, financial loss or any consequential
//loss can occur from a program failure. It is a demo only.

//The arduino code comprises a software UART RX that is 100% interrupt driven. It thereby frees up the
//the Arduino UNO uart. The program uses sampling to first detect the presence of a transmission
//and then samples the RX as the bits are recieved. 
//The 'Main' section is thus free from code apart from a few lines of Striker/relay driver code that gets
//instructions from the VB demo app. If the VB app is not used these lines can be deleted.

char rxVal, VBrx, outString,rxBytes[20];
const int per104uS = 207;
const int per100uS = 100; 
String hh; 
int relay = 13;
int ledPin = 9;

void setup(){
pinMode(7, INPUT);          //  RX input from ID12-LA module
digitalWrite(relay, LOW);   // put output reg to 'LOW" BEFOR making a port an output
digitalWrite(ledPin, LOW);   // put output reg to 'LOW" BEFOR making a port an output
pinMode(ledPin, OUTPUT);    // Relay LED
pinMode(relay, OUTPUT);     // Relay 
Serial.begin(9600);   
 
cli();//stop interrupts
  TCCR2A = 00;// TCCR2A = 0   // set reg TCCR2A to 0
  TCCR2B = 00;// TCCR2B = 0   // set reg TCCR2A to 0
  OCR2A = per100uS;           // set OCR2A timer period      
  TCCR2A |= (1 << WGM21);     // set TCCR2A 
  TCCR2B |= (1 << CS21);      // set CS21 
  TIMSK2 |= (1 << OCIE2A);    // set OCIE2A 
  TCNT2  = 00;//counter= 0    // set counter to 0
sei();//allow interrupts
 //Serial.println("OK, we are off");
 //Serial.println("");
}//end setup  

// Timer interrupt handles entire pin7 rx input. Leaves 'main' free for application. 
// Hard-wired changes to timer period for speed
ISR(TIMER2_COMPA_vect){//Timer vector 
valbool = digitalRead(7);  
 if (rxActive){    
  bitcnt +=1;
  timeout +=1; 
  if (bitcnt > 0){
    if (bitcnt < 9){
     if (valbool){
      rxVal = rxVal + (1 << (bitcnt - 1));    
  }}}  
  if (bitcnt==10){
    rxBytes[bytcnt] = (rxVal); 
    bitcnt=0;
    timeout=0;
    rxVal = 0;
    bytcnt += 1;
    rxActive = false;  
    TCCR2A = 00;// TCCR2A = 0
    TCCR2B = 00;// TCCR2B = 0
    OCR2A = per100uS; 
    TCCR2A |= (1 << WGM21);
    TCCR2B |= (1 << CS21);    
    TIMSK2 |= (1 << OCIE2A);
    TCNT2  = 00;//counter= 0 
      if (bytcnt >= 16){
         bytcnt=0; 
         hh = "";
         timeout = 0;       
         for (int n = 1; n <11 ; n++){      
         hh = hh + (rxBytes[n]);                  
        }
        Serial.print(hh);           
        Serial.print(" ");   // only for VB demo app use.
        VBtimeout = -100;
}}}   

  if (rxActive == false)
  {if(valbool == false){
    rxActive = true;
    TCCR2A = 00;// TCCR2A = 0
    TCCR2B = 00;// TCCR2B = 0
    OCR2A = per104uS; 
    TCCR2A |= (1 << WGM21);
    TCCR2B |= (1 << CS21);    
    TIMSK2 |= (1 << OCIE2A); 
    TCNT2  = 00;//counter= 0       
}}}
    
void loop(){                // Main loop. 
   VBrx="";
   VBrx = Serial.read();

VBtimeout ++;
if (strstr(VBrx, 'f' )){ 
   connected = 0; 
   VBtimeout = 0;    
} 

 delay(20);
   
if ( VBtimeout >10 )   {   
    connected = 0; 
   VBtimeout = 0;     
    hh="";   
    Serial.print('g');    
}
{   
 if ( VBrx == 'C' ) {
      Serial.print("w");
      delay(200);     
      connected=1;
}
}  
if ( VBrx == '1' ) 
      { 
      digitalWrite(relay, HIGH);
      delay(1000);
      digitalWrite(relay, LOW);    
}      
}    
